﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.WindowsCE.Forms;
using System.Drawing;
using System.Diagnostics;
using System.Reflection;
using System.ComponentModel;
using MeizuSDK.Core;
using MeizuSDK.Drawing;
using System.Threading;

namespace MeizuSDK.Presentation
{
    /// <summary>
    /// 表示组成应用程序用户界面的窗口或对话框
    /// </summary>
    public class Form : UIElement, IMzWindow
    {
        #region DllImport
        /// <summary>
        /// 获得窗口句柄对应的CMzWnd指针
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern IntPtr MzWndFromHandle(IntPtr hwnd);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern IntPtr MzWndExCtor([MarshalAs(UnmanagedType.LPWStr)]string pClassName, OnMzCommandFunc pOnMzCommand,
            MzDefWndProcFunc pWndProc, OnSettingChange pSettingChange, OnScreenRotated pScreenRotated, PaintWinFunc pOnPaintWin);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern void MzWndExDispose(IntPtr pObj);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern void MzWndExCreateWindow(IntPtr pObj, RECT rect);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern void MzWndExCreateChildWindow(IntPtr pObj, IntPtr hwndParent, RECT rect);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern void MzWndExCreateModalDialog(IntPtr pObj, IntPtr hwndParent, RECT rect);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        private static extern IntPtr MzWndExGetHWND(IntPtr pObj);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        internal static extern IntPtr MzWndExGetWindowBitmap(IntPtr pObj);

        [DllImport("MZFCWrapper.dll", SetLastError = true)]
        internal static extern IntPtr MzWndExGetWindowBitmapArea(IntPtr pObj, ref RECT prcScreen);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExAddUiWin(IntPtr pObj, IntPtr pWin);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExRemoveUiWin(IntPtr pObj, IntPtr pWin);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExShow(IntPtr pObj, bool isDialog, bool showAnimation, int animateInType);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExClose(IntPtr pObj, bool isDialog, int animateOutType);

        [DllImport("MZFCWrapper.dll")]
        private static extern int MzWndExHide(IntPtr pObj);

        //[DllImport("MZFCWrapper.dll")]
        //private static extern void MzWndExEndModal(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern int MzWndExGetWidth(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern int MzWndExGetHeight(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetFontColor(IntPtr pObj, uint crFont);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetBgColor(IntPtr pObj, uint crBg);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetWindowPos(IntPtr pObj, IntPtr hWndInsertAfter, int x, int y, int w, int h, uint flag);

        [DllImport("MZFCWrapper.dll")]
        private static extern IntPtr MzWndExGetWindowText(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetWindowText(IntPtr pObj, [MarshalAs(UnmanagedType.LPWStr)]string text);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExAnimateWindow(IntPtr pObj, uint nAnimType, bool bShow);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetAnimateType_Show(IntPtr pObj, int nAnimType);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExSetAnimateType_Hide(IntPtr pObj, int nAnimType);

        [DllImport("MZFCWrapper.dll")]
        private static extern void MzWndExUpdateWindow(IntPtr pObj);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzWndExInvalidate(IntPtr pObj, ref RECT rectUpdate, bool bErase);

        [DllImport("MZFCWrapper.dll")]
        private static extern bool MzWndExInvalidate2(IntPtr pObj, bool bErase);
        #endregion

        #region Touch Notify API

        [StructLayout(LayoutKind.Sequential)]
        public struct TOUCH_FINGER_DATA
        {
            public ushort x;
            public ushort y;
            public ushort z;
            public ushort wReserved;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct TOUCH_RAW_DATA
        {
            public int iSize;
            public ushort wFingers;
            public ushort wReserved;
            public TOUCH_FINGER_DATA FingerData1;
            public TOUCH_FINGER_DATA FingerData2;
        }

        [DllImport("PlatformAPIWrapper.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool TouchNotifyApiRegisterTouchNotifyEx(System.IntPtr hWnd, int iNotifyMsg, uint dwFlag);

        [DllImport("PlatformAPIWrapper.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool TouchNotifyApiUnRegisterTouchNotify(System.IntPtr hWnd, int iNotifyMsg);

        [DllImport("PlatformAPIWrapper.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool TouchNotifyApiGetTouchRawData(ref TOUCH_RAW_DATA pRawData);

        const int TCH_NOTIFY_FLAG_RAWDATA = 0x02;

        #endregion

        #region 常量
        /// <summary>
        /// 多点触摸消息
        /// </summary>
        const int MZ_WM_TOUCH = 0x00FF0001;
        /// <summary>
        /// 程序激活消息
        /// </summary>
        const int WM_ACTIVE = 0x0006;

        #region 转屏参数
        /// <summary>
        /// 竖屏——正常状态
        /// </summary>
        const uint Screen_Angle_0 = 0;
        /// <summary>
        /// 横屏——相对正常方向顺时针旋转90°
        /// </summary>
        const uint Screen_Angle_90 = 3;
        /// <summary>
        /// 竖屏——相对正常状态顺时针旋转180°
        /// </summary>
        const uint Screen_Angle_180 = 1;
        /// <summary>
        /// 横屏——相对正常状态顺时针旋转270°
        /// </summary>
        const uint Screen_Angle_270 = 2;
        #endregion

        #endregion

        #region 事件
        /// <summary>
        /// 当窗口关闭后引发此事件
        /// </summary>
        public event EventHandler Closed;
        /// <summary>
        /// 窗口关闭前引发此事件
        /// </summary>
        public event EventHandler<CancelEventArgs> Closing;
        /// <summary>
        /// 当窗口中存在多个触摸点时，引发此事件
        /// </summary>
        public event EventHandler<MultiTouchEventArgs> Touch;
        /// <summary>
        /// 窗口加载时触发此事件
        /// </summary>
        public event EventHandler Load;
        /// <summary>
        /// 当窗口需要重新绘制时触发此事件
        /// </summary>
        public event PaintEventHandler Paint;
        /// <summary>
        /// 当应用程序被设置为不可以使用M键关闭时，按下M键，触发此事件
        /// </summary>
        public event EventHandler MKeyClicked;
        /// <summary>
        /// 当屏幕显示方向被改编后触发此事件
        /// </summary>
        public event ScreenRotatedEventHandler ScreenRotated;
        #endregion

        #region 私有变量

        private OnMzCommandFunc pOnMzCommandFunc;
        private MzDefWndProcFunc pMzDefWndProcFunc;
        private OnSettingChange pOnSettingChange;
        private OnScreenRotated pOnScreenRotated;
        private PaintWinFunc pOnPaintWin;
        /// <summary>
        /// USB消息
        /// </summary>
        private int usbmsg;
        /// <summary>
        /// 指示窗口是否是对话框
        /// </summary>
        private bool isDoModal;
        /// <summary>
        /// 窗口返回值
        /// </summary>
        private DialogResult dialogResult;
        /// <summary>
        /// 窗口句柄
        /// </summary>
        private IntPtr hWnd;
        /// <summary>
        /// 窗口打开时的动画效果
        /// </summary>
        private AnimationType animationIn;
        /// <summary>
        /// 窗口关闭时的动画效果
        /// </summary>
        private AnimationType animationOut;
        /// <summary>
        /// 背景图片
        /// </summary>
        private Image bgImage;
        /// <summary>
        /// 进行处理过的背景缓存图片
        /// </summary>
        private Image bufferBgImage;
        /// <summary>
        /// 父窗口的位图
        /// </summary>
        private IntPtr preWndBitmap = IntPtr.Zero;
        /// <summary>
        /// 窗口背景颜色
        /// </summary>
        private Color bgColor;
        /// <summary>
        /// 窗口位置
        /// </summary>
        private Point location;
        /// <summary>
        /// 加速度传感器
        /// </summary>
        private GravitySensor gravitySensor;
        /// <summary>
        /// 系统转屏消息
        /// </summary>
        private uint screenRotateMessage;
        #endregion

        #region 公共属性
        /// <summary>
        /// 获取或设置一个值，指示此窗口是否是主窗口
        /// </summary>
        public bool IsMainWindow
        {
            get
            {
                return (IsHandleCreated && Application.MainWindow == this);
            }
        }
        /// <summary>
        /// 获取父窗口的显示位图
        /// </summary>
        internal IntPtr ParentWndImage
        {
            get
            {
                return preWndBitmap;
            }
        }
        /// <summary>
        /// 获取一个值，该值指示调用方在对窗口进行方法调用时是否必须调用 Invoke 方法，因为调用方位于创建窗口所在的线程以外的线程中。
        /// </summary>
        public bool InvokeRequired
        {
            get
            {
                uint num = 0;

                if (!IsHandleCreated)
                {
                    return false;
                }

                int windowThreadProcessId = NativeMethods.GetWindowThreadProcessId(hWnd, ref num);

                int currentThreadId = NativeMethods.GetCurrentThreadId();

                return (windowThreadProcessId != currentThreadId);
            }
        }
        /// <summary>
        /// 获取此窗口句柄
        /// </summary>
        public IntPtr HWnd
        {
            get
            {
                return hWnd;
            }
        }
        /// <summary>
        /// 获取父窗口实例
        /// </summary>
        public IMzWindow ParentWindow
        {
            get;
            protected set;
        }
        /// <summary>
        /// 获取或设置窗口背景图片
        /// </summary>
        public Image BackgroundImage
        {
            get
            {
                return this.bgImage;
            }
            set
            {
                if (value != bgImage)
                {
                    bgImage = value;

                    BufferBackgroundImage = value;

                    Invalidate();
                    Update();
                }
            }
        }
        /// <summary>
        /// 获取或设置经过缩放处理的背景图片
        /// </summary>
        protected Image BufferBackgroundImage
        {
            get
            {
                return this.bufferBgImage;
            }
            set
            {
                if (value != this.bufferBgImage)
                {
                    if (value == null)
                    {
                        this.bufferBgImage = null;
                        return;
                    }

                    this.bufferBgImage = new Bitmap(Width, Height);

                    using (Graphics g = Graphics.FromImage(this.bufferBgImage))
                    {
                        Rectangle imgRect = new Rectangle(0, 0, BackgroundImage.Width, BackgroundImage.Height);
                        g.DrawImage(BackgroundImage, ClientRectangle, imgRect, GraphicsUnit.Pixel);
                    }
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口文本颜色
        /// </summary>
        public override Color ForeColor
        {
            get
            {
                return base.ForeColor;
            }
            set
            {
                base.ForeColor = value;
                if (IsHandleCreated)
                {
                    int rgb = MzDrawHelper.GetRGB(value);
                    MzWndExSetFontColor(Handle, (uint)rgb);
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口背景颜色
        /// </summary>
        public Color BackgroundColor
        {
            get
            {
                return bgColor;
            }
            set
            {
                bgColor = value;
                if (IsHandleCreated)
                {
                    int rgb = MzDrawHelper.GetRGB(value);
                    MzWndExSetBgColor(Handle, (uint)rgb);
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口大小
        /// </summary>
        public override Size Size
        {
            get
            {
                return base.Size;
            }
            set
            {
                if (value != Size)
                {
                    base.Size = value;

                    if (IsHandleCreated)
                    {
                        MzWndExSetWindowPos(Handle, IntPtr.Zero, 0, 0, value.Width, value.Height, MzUser.SP_NOMOVE);

                        OnSizeChanged(EventArgs.Empty);
                    }
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口高度
        /// </summary>
        public override int Height
        {
            get
            {
                return Size.Height;
            }
            set
            {
                if (value != Height)
                {
                    Size = new Size(Width, value);
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口宽度
        /// </summary>
        public override int Width
        {
            get
            {
                return Size.Width;
            }
            set
            {
                if (value != Width)
                {
                    //base.Width = value;
                    //if (IsHandleCreated)
                    //{
                    //    MzWndExSetWindowPos(Handle, IntPtr.Zero, 0, 0, value, Height, MzUser.SP_NOMOVE);
                    //    OnSizeChanged(EventArgs.Empty);
                    //}
                    Size = new Size(value, Height);
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口的位置
        /// </summary>
        public override Point Location
        {
            get
            {
                return this.location;
            }
            set
            {
                if (value != this.location)
                {
                    this.location = value;

                    if (IsHandleCreated)
                    {
                        MzWndExSetWindowPos(Handle, IntPtr.Zero, this.location.X, this.location.Y, Width, Height, MzUser.SP_NOSIZE);
                        OnLocationChanged(EventArgs.Empty);
                    }
                }
            }
        }
        /// <summary>
        /// 获取窗口客户区域矩形
        /// </summary>
        public override Rectangle ClientRectangle
        {
            get
            {
                return new Rectangle(0, 0, Width, Height);
            }
        }
        /// <summary>
        /// 获取窗口的客户区域大小
        /// </summary>
        public override Size ClientSize
        {
            get
            {
                return Size;
            }
        }
        /// <summary>
        /// 获取或设置窗口文本
        /// </summary>
        public override string Text
        {
            get
            {
                return base.Text;
            }
            set
            {
                base.Text = value;
                if (IsHandleCreated)
                    MzWndExSetWindowText(Handle, value);
            }
        }
        /// <summary>
        /// 获取或设置窗口打开时的动画效果
        /// </summary>
        public AnimationType AnimationIn
        {
            get
            {
                return animationIn;
            }
            set
            {
                if (value != animationIn)
                {
                    animationIn = value;
                }
            }
        }
        /// <summary>
        /// 获取或设置窗口关闭时的动画效果
        /// </summary>
        public AnimationType AnimationOut
        {
            get
            {
                return animationOut;
            }
            set
            {
                if (value != animationOut)
                {
                    animationOut = value;
                }
            }
        }
        /// <summary>
        /// 获取一个标志，指示此窗口是否以对话框形式显示
        /// </summary>
        public bool IsDialog
        {
            get
            {
                return isDoModal;
            }
        }
        /// <summary>
        /// 获取或设置窗体的对话框结果。
        /// </summary>
        public DialogResult DialogResult
        {
            get
            {
                return this.dialogResult;
            }
            set
            {
                this.dialogResult = value;

                if (isDoModal)
                {
                    switch (this.dialogResult)
                    {
                        case DialogResult.Yes:
                        case DialogResult.OK:
                            Close();
                            break;
                    }
                }
            }
        }
        /// <summary>
        /// 获取PaintWin函数委托
        /// </summary>
        protected PaintWinFunc PaintWinDelegate
        {
            get
            {
                if (this.pOnPaintWin == null)
                {
                    this.pOnPaintWin = new PaintWinFunc(InternalPaintWin);
                }
                return this.pOnPaintWin;
            }
        }
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造窗口实例
        /// </summary>
        public Form()
        {
            pOnMzCommandFunc = new OnMzCommandFunc(OnMzCommand);
            pMzDefWndProcFunc = new MzDefWndProcFunc(MzDefWndProc);
            pOnSettingChange = new OnSettingChange(InternalOnSettingChange);
            pOnScreenRotated = new OnScreenRotated(InternalOnScreenRotated);

            // 窗口动画
            AnimationIn = AnimationType.ZoomIn;
            AnimationOut = AnimationType.ZoomOut;

            // 将默认文本颜色设置为黑色
            ForeColor = Color.Black;
            // 设置窗口背景色
            BackgroundColor = MzSystemColors.Window_BgColor;
            // 设置对话框结果
            DialogResult = DialogResult.None;
            // 重设窗口工作区域
            ResetFormWorkArea();

            // TODO: Guesture Not implemented 
            // FIXME: Always return false
            //TouchNotifyApiRegisterTouchNotifyEx(pObj, MZ_WM_TOUCH, TCH_NOTIFY_FLAG_RAWDATA);

            // USB消息
            usbmsg = UsbConnection.NotifyMessage;

            // 任务栏可视化事件
            Application.TaskBarVisibleChanged += new EventHandler(Application_TaskBarVisibleChanged);
            // 重力横屏
            Application.AutoRotateScreenChanged += new EventHandler(Application_AutoRotateScreenChanged);

            if(Application.AutoRotateScreen)
            {
                screenRotateMessage = GravitySensor.Instance.Message;
            }
            else
            {
                screenRotateMessage = 0;
            }
        }
        #endregion

        #region 函数
        /// <summary>
        /// 当程序是否支持重力横屏选项被改变时触发此事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_AutoRotateScreenChanged(object sender, EventArgs e)
        {
            gravitySensor = GravitySensor.Instance;

            if (Application.AutoRotateScreen)
            {
                screenRotateMessage = gravitySensor.Message;
            }
            else
            {
                screenRotateMessage = 0;
            }
        }
        /// <summary>
        /// 任务栏可视性改变后触发此事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Application_TaskBarVisibleChanged(object sender, EventArgs e)
        {
            if (IsHandleCreated)
                ResetFormWorkArea();
        }
        /// <summary>
        /// 重设窗口工作区域
        /// </summary>
        private void ResetFormWorkArea()
        {
            // 设置窗口大小
            Size = new Size(Screen.ClientWidth, Screen.ClientHeight);

            // 设置位置
            Location = new Point(0, Application.IsShowTaskBar ? Screen.TaskBarHeight : 0);
        }
        /// <summary>
        /// 作窗口动画
        /// </summary>
        /// <param name="animateType">窗口动画类型</param>
        /// <param name="bShow">为true，表示显示窗口打开动画；false，表示显示窗口关闭动画</param>
        public void AnimateWindow(AnimationType animateType, bool bShow)
        {
            if (IsHandleCreated)
                return;

            uint aniType = (uint)animateType;

            MzWndExAnimateWindow(Handle, aniType, bShow);
        }
        /// <summary>
        /// 初始化窗口
        /// </summary>
        /// <param name="hwndParent">父窗口句柄</param>
        /// <param name="doModal">是否为打开对话框</param>
        private void InitializeForm(IntPtr hwndParent, bool doModal)
        {
            // 重设窗口工作区域
            ResetFormWorkArea();

            // 创建窗口对象实例
            Handle = MzWndExCtor(Application.AppId, pOnMzCommandFunc, pMzDefWndProcFunc, pOnSettingChange, pOnScreenRotated, PaintWinDelegate);

            // 工作区域
            RECT rect = RECT.FromXYWH(Location.X, Location.Y, Width, Height);

            // 创建窗口
            if (!doModal)
            {
                if (hwndParent != IntPtr.Zero)
                    MzWndExCreateChildWindow(Handle, ParentWindow.HWnd, rect);
                else
                    MzWndExCreateWindow(Handle, rect);
            }
            else
            {
                MzWndExCreateModalDialog(Handle, hwndParent, rect);
            }

            // 设置窗口动画
            if (!IsMainWindow)
            {
                MzWndExSetAnimateType_Show(Handle, (int)AnimationIn);
                MzWndExSetAnimateType_Hide(Handle, (int)AnimationOut);
            }

            // 获取窗口句柄
            hWnd = MzWndExGetHWND(Handle);

            // 设置前景色
            int rgb = MzDrawHelper.GetRGB(ForeColor);
            MzWndExSetFontColor(Handle, (uint)rgb);

            // 设置背景色
            rgb = MzDrawHelper.GetRGB(BackgroundColor);
            MzWndExSetBgColor(Handle, (uint)rgb);

            // 设置文本
            MzWndExSetWindowText(Handle, Text);

            // 加载控件
            foreach (Control ctr in Controls)
            {
                AddChild(ctr);
            }
        }
        /// <summary>
        /// 初始化窗口内组件（可以在此函数中加载控件。此函数加载顺序在OnLoad函数之前）
        /// </summary>
        protected virtual void InitializeComponents()
        {
            // TODO：子类实现
        }
        /// <summary>
        /// 引发 Load 事件。（OnLoad在InitializeComponents函数之后被调用）
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnLoad(EventArgs e)
        {
            if (this.Load != null)
            {
                this.Load(this, e);
            }
        }
        /// <summary>
        /// 显示窗口
        /// </summary>
        public void Show()
        {
            Show(null);
        }
        /// <summary>
        /// 显示窗口
        /// </summary>
        /// <param name="parent">当前窗口的父窗口</param>
        public void Show(IMzWindow parent)
        {
            InternalShow(parent, false);
        }
        /// <summary>
        /// 将窗口以模态对话框形式显示
        /// </summary>
        public DialogResult ShowDialog()
        {
            return ShowDialog(null);
        }
        /// <summary>
        /// 将窗口以模态对话框形式显示
        /// </summary>
        /// <param name="parent">父窗口</param>
        public DialogResult ShowDialog(IMzWindow parent)
        {
            DialogResult = DialogResult.None;

            InternalShow(parent, true);

            return dialogResult;
        }
        /// <summary>
        /// 内部显示窗口函数
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="doModal"></param>
        private void InternalShow(IMzWindow parent, bool doModal)
        {
            isDoModal = doModal;
            dialogResult = DialogResult.None;

            IMzWindow hwndParent = (Application.MainWindow != null && Application.MainWindow.IsHandleCreated) ? Application.MainWindow : null;

            if (parent != null)
            {
                hwndParent = parent;
            }

            // 初始化窗口
            InitializeForm(hwndParent == null ? IntPtr.Zero : hwndParent.HWnd, doModal);

            // 设置父窗口
            if (parent != null)
            {
                ParentWindow = parent;
            }
            else
            {
                ParentWindow = Application.MainWindow;
            }

            // 初始化窗口内部组件
            InitializeComponents();

            // 触发窗口已加载事件
            OnLoad(EventArgs.Empty);

            // 显示对话框
            MzWndExShow(Handle, isDoModal, IsMainWindow && Application.UseAppStartAnimation, (int)this.AnimationIn);
        }
        /// <summary>
        /// 隐藏窗口
        /// </summary>
        public void Hide()
        {
            if (isDoModal)
            {
                return;
            }
            AnimateWindow(AnimationOut, false);
            MzWndExHide(Handle);
        }
        /// <summary>
        /// 关闭窗口
        /// </summary>
        public void Close()
        {
            CancelEventArgs e = new CancelEventArgs();

            OnClosing(e);

            if (!e.Cancel)
            {
                try
                {
                    MzWndExClose(Handle, isDoModal, (int)this.AnimationOut);
                }
                catch (System.Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
                finally
                {
                    Dispose();

                    OnClosed(EventArgs.Empty);
                }
            }
        }
        /// <summary>
        /// 更新窗口
        /// </summary>
        public override void Update()
        {
            if (!IsHandleCreated)
                return;
            MzWndExUpdateWindow(Handle);
        }
        /// <summary>
        /// 使窗口失效
        /// </summary>
        public override void Invalidate()
        {
            Invalidate(Rectangle.Empty);
        }
        /// <summary>
        /// 使窗口的某部分失效
        /// </summary>
        /// <param name="rectUpdate"></param>
        public override void Invalidate(Rectangle rectUpdate)
        {
            Invalidate(rectUpdate, false);
        }
        /// <summary>
        /// 使窗口的某部分失效
        /// </summary>
        /// <param name="updateRect">更新区域</param>
        /// <param name="bErase"></param>
        public void Invalidate(Rectangle updateRect, bool bErase)
        {
            if (!IsHandleCreated)
                return;

            bool result = false;

            if (updateRect != Rectangle.Empty)
            {
                RECT rect = RECT.FromRectangle(updateRect);

                result = MzWndExInvalidate(Handle, ref rect, bErase);
            }
            else
            {
                MzWndExInvalidate2(Handle, bErase);
            }
        }
        /// <summary>
        /// 添加子控件
        /// </summary>
        /// <param name="control"></param>
        internal override void AddChild(Control control)
        {
            if (IsHandleCreated)
                MzWndExAddUiWin(Handle, control.Handle);
        }
        /// <summary>
        /// 移除子控件
        /// </summary>
        /// <param name="control"></param>
        internal override void RemoveChild(Control control)
        {
            if (IsHandleCreated)
                MzWndExRemoveUiWin(Handle, control.Handle);
        }
        /// <summary>
        /// 获取设备上下文
        /// </summary>
        /// <returns></returns>
        public IntPtr GetDC()
        {
            if (IsHandleCreated)
                return NativeMethods.GetDC(HWnd);
            return IntPtr.Zero;
        }
        /// <summary>
        /// 释放设备上下文
        /// </summary>
        /// <param name="dc"></param>
        public void ReleaseDC(IntPtr dc)
        {
            int result = 0;
            if (IsHandleCreated)
            {
                result = NativeMethods.ReleaseDC(HWnd, dc);
            }
        }
        /// <summary>
        /// 当收到WM_Paint消息时调用此函数进行重绘
        /// </summary>
        /// <param name="hdcDst"></param>
        /// <param name="prcWin"></param>
        /// <param name="prcUpdate"></param>
        private void InternalPaintWin(IntPtr hdcDst, ref RECT prcWin, ref RECT prcUpdate)
        {
            if (hdcDst == IntPtr.Zero || !IsHandleCreated)
                return;

            using (Graphics g = Graphics.FromHdc(hdcDst))
            {
                PaintEventArgs e = new PaintEventArgs(g, Rectangle.Empty, prcUpdate.ToRectangle());
                OnPaintBackground(e);
                OnPaint(e);
            }
        }
        /// <summary>
        /// 绘制背景函数
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnPaintBackground(PaintEventArgs e)
        {
            // 这里使用已经进行处理的缓存背景图片进行绘图

            if (this.BufferBackgroundImage == null)
                return;

            Graphics g = e.Graphics;

            g.DrawImage(BufferBackgroundImage, e.UpdateRectangle, e.UpdateRectangle, GraphicsUnit.Pixel);
        }
        /// <summary>
        /// 引发 Paint 事件
        /// </summary>
        /// <param name="e">Paint事件参数</param>
        protected virtual void OnPaint(PaintEventArgs e)
        {
            if (this.Paint != null)
            {
                this.Paint(this, e);
            }
        }
        /// <summary>
        /// 引发 Closing 事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnClosing(CancelEventArgs e)
        {
            if (Closing != null)
                Closing(this, e);
        }
        /// <summary>
        /// 引发 Closed 事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnClosed(EventArgs e)
        {
            if (Closed != null)
                Closed(this, EventArgs.Empty);
        }
        /// <summary>
        /// 引发 MKeyClicked 事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnMKeyClicked(EventArgs e)
        {
            if (MKeyClicked != null)
                MKeyClicked(this, EventArgs.Empty);
        }
        /// <summary>
        /// This method is for internal interop use.
        /// 当窗口收到 WM_COMMAND 消息时，会调用此成员函数 
        /// </summary>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        protected virtual void OnMzCommand(uint wParam, uint lParam)
        {
            int id = (int)(wParam & 0x0000FFFF);
            Control ctr = Controls.FindControlById(id);
            if (ctr != null)
                ctr.OnMzCommand(wParam, lParam);
        }
        /// <summary>
        /// 当接收WM_SETTINGCHANGE消息后调用此函数
        /// </summary>
        /// <param name="wFlag"></param>
        /// <param name="pszSectionName"></param>
        private void InternalOnSettingChange(uint wFlag, string pszSectionName)
        {

        }
        /// <summary>
        /// 当屏幕显示方向被改变后调用此函数
        /// </summary>
        /// <param name="dmDisplayOrientation"></param>
        private void InternalOnScreenRotated(uint dmDisplayOrientation)
        {
            if (Enum.IsDefined(typeof(ScreenRotationAngle), dmDisplayOrientation))
            {
                // 当屏幕方向改变后，需要重新设置窗口大小、位置
                ResetFormWorkArea();

                // 获取当前屏幕显示方向
                ScreenRotationAngle angle = (ScreenRotationAngle)dmDisplayOrientation;
                // 当屏幕显示方向发生改变后，调用此函数重新布局控件
                RelayoutControls(angle);
                // 准备ScreenRotated事件参数
                ScreenRotatedEventArgs e = new ScreenRotatedEventArgs(angle);
                // 触发ScreenRotated事件
                OnScreenRotated(e);
            }
        }
        /// <summary>
        /// 当屏幕显示方向发生改变后，调用此函数重新布局控件
        /// </summary>
        /// <param name="orientation"></param>
        protected virtual void RelayoutControls(ScreenRotationAngle orientation)
        {

        }
        /// <summary>
        /// 触发ScreenRotated事件
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnScreenRotated(ScreenRotatedEventArgs e)
        {
            if (ScreenRotated != null)
            {
                ScreenRotated(this, e);
            }
        }
        /// <summary>
        /// 处理窗口消息
        /// </summary>
        /// <param name="message"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        internal uint MzDefWndProc(uint message, uint wParam, uint lParam)
        {
            switch (message)
            {
                // 将鼠标消息传递给控件
                case MzUser.MZ_MOUSE_DOWN_MOVE:
                case MzUser.MZ_MOUSE_RELEASED:
                case MzUser.MZ_WM_MOUSE_NOTIFY:
                    int id = (int)(wParam & 0x0000FFFF);
                    Control ctrl = Controls.FindControlById(id);
                    if (ctrl != null)
                    {
                        ctrl.MzDefWndProc(message, wParam, lParam);
                    }
                    break;

                case MZ_WM_TOUCH:
                    {
                        OnTouch();
                    }
                    break;
                default:
                    {
                        // 将非鼠标消息传递给控件
                        Controls.MzDefWndProc(message, wParam, lParam);

                        if (message == usbmsg)
                        {
                            UsbConnection.OnStatusChanged(wParam);
                        }
                        // 转屏消息
                        if (screenRotateMessage != 0 &&
                            message == screenRotateMessage)
                        {
                            // 转屏
                            switch (wParam)
                            {
                                // 转屏90°
                                case Screen_Angle_90:
                                    {
                                        Screen.Rotate(ScreenRotationAngle.Angle_90, !Application.IsShowTaskBar);
                                    }
                                    break;
                                // 转屏180°
                                case Screen_Angle_180:
                                    {
                                        Screen.Rotate(ScreenRotationAngle.Angle_180, !Application.IsShowTaskBar);
                                    }
                                    break;
                                // 转屏270°
                                case Screen_Angle_270:
                                    {
                                        Screen.Rotate(ScreenRotationAngle.Angle_270, !Application.IsShowTaskBar);
                                    }
                                    break;
                                // 屏幕恢复正常方向
                                case Screen_Angle_0:
                                default:
                                    {
                                        Screen.Rotate(ScreenRotationAngle.Angle_0, !Application.IsShowTaskBar);
                                    }
                                    break;
                            }
                        }
                    }
                    break;
            }

            WndProc(message, wParam, lParam);

            // 判断当前是否按下了M键
            if (message == Application.HomeKeyMessage)
            {
                if (!Application.IsNeverQuit)
                {
                    NativeMethods.PostMessage(IntPtr.Zero, NativeMethods.WM_QUIT, 0, 0);
                }
                else
                {
                    OnMKeyClicked(EventArgs.Empty);
                }
            }

            return 0;
        }

        /// <summary>
        /// 引发 Touch 事件
        /// </summary>
        protected void OnTouch()
        {
            if (Touch != null)
                Touch(this, new MultiTouchEventArgs(Handle));
        }

        #region 销毁资源

        /// <summary>
        /// 销毁资源
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            //if (!disposed)
            {
                if (disposing)
                {
                    if (BufferBackgroundImage != null)
                    {
                        BufferBackgroundImage.Dispose();
                    }

                    if (BackgroundImage != null)
                    {
                        BackgroundImage.Dispose();
                    }
                }

                TouchNotifyApiUnRegisterTouchNotify(Handle, MZ_WM_TOUCH);

                MzWndExDispose(Handle);
            }
        }
        #endregion

        #endregion

        /// <summary>
        /// 多点触摸事件参数
        /// </summary>
        public class MultiTouchEventArgs : EventArgs
        {
            IntPtr hWnd;
            List<TouchData> touches;

            /// <summary>
            /// 构造多点触摸事件参数
            /// </summary>
            /// <param name="hWnd"></param>
            public MultiTouchEventArgs(IntPtr hWnd)
            {
                this.hWnd = hWnd;
                touches = new List<TouchData>();

                TOUCH_RAW_DATA data = new TOUCH_RAW_DATA();
                TouchNotifyApiGetTouchRawData(ref data);

                if (data.wFingers > 0)
                    touches.Add(new TouchData() { X = data.FingerData1.x, Y = data.FingerData1.y, Z = data.FingerData1.z });

                if (data.wFingers > 1)
                    touches.Add(new TouchData() { X = data.FingerData2.x, Y = data.FingerData2.y, Z = data.FingerData2.z });
            }
            /// <summary>
            /// 获取触摸点信息列表
            /// </summary>
            public List<TouchData> Touches
            {
                get
                {
                    return touches;
                }
            }
        }
        /// <summary>
        /// 触摸点数据对象
        /// </summary>
        public class TouchData
        {
            /// <summary>
            /// X坐标
            /// </summary>
            public int X;
            /// <summary>
            /// Y坐标
            /// </summary>
            public int Y;
            /// <summary>
            /// Z坐标
            /// </summary>
            public int Z;
        }
    }
}
